package tesis.sin.rest.clasesusuario;

import java.io.IOException;
import java.io.Serializable;
import java.util.Map;
import java.util.Map.Entry;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.NotFoundException;

public class GeneradorClase {
	
	public static Class generarClase(String nombre, Map<String, Class<?>>  propiedades) throws NotFoundException, CannotCompileException, IOException
	{
		ClassPool pool = ClassPool.getDefault();
		CtClass cc = pool.makeClass(nombre);		
		cc.addInterface(resolverClaseCt(Serializable.class));

		for(Entry entry : propiedades.entrySet())
		{
			CtClass ctClass = resolverClaseCt((Class)entry.getValue());
			cc.addField(new CtField(ctClass, (String)entry.getKey(),cc));
			cc.addMethod(generarGetter(cc, (String)entry.getKey(), (Class)entry.getValue()));
			cc.addMethod(generarSetter(cc, (String)entry.getKey(), (Class)entry.getValue()));
		}
		
		cc.writeFile("D://Benjamin//Workspace//SIN//srcUsuario//");
		return cc.toClass();
	}
	
	private static CtClass resolverClaseCt(Class clazz) throws NotFoundException {
		ClassPool pool = ClassPool.getDefault();
		return pool.get(clazz.getName());
	}

	private static CtMethod generarGetter(CtClass declaringClass, String fieldName, Class fieldClass) throws CannotCompileException
	{
		String getterName = "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
		StringBuffer sb = new StringBuffer();
		sb.append("public ").append(fieldClass.getName()).append(" ").append(getterName).append("(){").append("return this.").append(fieldName).append(";").append("}");
		return CtMethod.make(sb.toString(), declaringClass);
	}

	private static CtMethod generarSetter(CtClass declaringClass, String fieldName, Class fieldClass) throws CannotCompileException
	{
		String setterName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
		StringBuffer sb = new StringBuffer();
		sb.append("public void ").append(setterName).append("(").append(fieldClass.getName()).append(" ").append(fieldName).append(")").append("{").append("this.").append(fieldName).append("=").append(fieldName).append(";").append("}");
		return CtMethod.make(sb.toString(), declaringClass);
	}	
}
